package o.gwtp.editor.client.navigation;

import java.util.LinkedList;
import java.util.List;

import o.gwtp.editor.client.editor.EditorPresenter.EditorProxy;
import o.gwtp.editor.client.editor.EditorProxyFactory;
import o.gwtp.editor.client.navigation.CloseTabEvent.CloseTabHandler;
import o.gwtp.editor.client.navigation.NavigationTabEvent.NavigationTabHandler;
import o.gwtp.editor.client.navigation.NavigationTabView.MyControls;

import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.EventBus;
import com.gwtplatform.mvp.client.HasControls;
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;

/**
 * @author Olivier Monaco
 * @author Christian Goudreau
 */
public class NavigationTabPresenter extends
    PresenterWidget<NavigationTabPresenter.MyView> implements
    NavigationTabHandler, MyControls {
  public interface MyView extends View, HasControls<MyControls> {
    void createTab(Widget tabElement);

    void removeTab(int index);

    void selectTab(int index);
  }

  private List<NavigationTabElement> elements = new LinkedList<NavigationTabElement>();
  private EditorProxyFactory editorFactory;
  private final PlaceManager placeManager;

  @Inject
  public NavigationTabPresenter(EventBus eventBus, MyView view,
      EditorProxyFactory editorFactory, PlaceManager placeManager) {
    super(eventBus, view);
    
    getView().setControls(this);
    addRegisteredHandler(NavigationTabEvent.getType(), this);
    this.editorFactory = editorFactory;
    this.placeManager = placeManager;
  }

  @Override
  public void onCloseTab(NavigationTabElement element) {
    int index = elements.indexOf(element);
    getView().removeTab(index);
    elements.remove(index);
    if (index >= elements.size()) {
      index = elements.size() - 1;
    }
    onTabSelected(index);
  }

  @Override
  public void onNewRequest(String name) {
    EditorProxy proxy = editorFactory.create(name);

    placeManager.revealPlace(new PlaceRequest(proxy.getNameToken()));
  }

  @Override
  public void onRevealTab(NavigationTabElement element) {
    if (!elements.contains(element)) {
      getView().createTab(createTab(element));
      elements.add(element);
    }
    getView().selectTab(elements.indexOf(element));
  }

  @Override
  public void onTabSelected(int index) {
    placeManager.revealPlace(new PlaceRequest(elements.get(index).getToken()));
  }
  
  private Widget createTab(final NavigationTabElement element) {
    TabElement tabElement = new TabElement(element.getName(), element.isClosable());
    
    tabElement.addCloseTabHandler(new CloseTabHandler() {
      @Override
      public void onCloseTab(CloseTabEvent event) {
        onTabClosed(elements.indexOf(element));
      }
    });
    
    return tabElement;
  }

  private void onTabClosed(int index) {
    NavigationTabEvent.fireClose(this, elements.get(index));
  }
}
